#ifndef ZIPPER_H_
#define ZIPPER_H_

#include <zipfile.h>

#include <vector>
#include <string>
#include <exception>
#include <cstring>
#include <boost/utility.hpp>
#include "Tools.h"
#include "../Validator/Scheme.h"
#include "PFileInfo.h"


//! Zipper trieda.
/*!
 	Trieda sluziaca na pracu s archivnym suborom typu zip.
	Umoznuje extrakciu suborov a ziskanie validacnej schemy suboru
	Trieda sa neda kopirovat !!! dedi od boost::noncopyable !!!
*/
class Zipper : boost::noncopyable
{
	public:
		//! Constructor
		/*!
			Zakladny konstruktor triedy, prazdny meta subor
			\param theArchiv subor typu zip zapuzdreny v triede PFileInfo
		*/
		Zipper(PComunicator::PFileInfo theArchiv);

		//! Destructor
		/*!
			Destruktor triedy sluziaci na odstranenie objektov z haldy
		*/
		~Zipper(void);

		//! Extract
		/*!
			Extrahuje dany subor do triedy PFileInfo
			\param theFileName nazov suboru ktory sa ma extrahovat
			\param ptheOutput trieda typu PFileInfo do ktorej sa ma extrakcia vykonat
			\return true ak extrakcia je uspesna, false inak
		*/
		bool Extract(std::string theFileName, PComunicator::PFileInfo **pOut);


		//! ExtractNoType (public )
		/*!
			Extrahuje dany subor pricom nezalezi na jeho type
			bere ohlad len na nazov suboru
			\param std::string theFileName nazov suboru bez typu
			\param PComunicator::PFileInfo ** pOut extrahovany subor
			\return bool true ak extrakcia je uspesna, false inak
		*/
		bool ExtractNoType(std::string theFileName, PComunicator::PFileInfo **pOut);

		//! IsInArchive
		/*!
			Zisti ci dany subor sa nachadza v archivacnom subore alebo ne
			\param theFileName nazov suboru
			\return true ak subor existuje, false inak
		*/
		bool IsInArchive(std::string theFileName);

		//! GetScheme
		/*!
			Navrati Schemu pre dany archivacny subor
			\return Scheme archivacneho suboru
		*/
		const Validator::Scheme& GetScheme(void) const;

	private:
		Validator::Scheme *myScheme;
		zipios::ZipFile *myZipFile;
		void BuildScheme(std::string theName);
		void ParseDirectory(std::string theInput,std::vector<Validator::MetaDirectory> &theDirColl);
		void ParseFile(std::string theInput,std::vector<std::pair<Validator::MetaFile,std::string> > &theFileColl);
		void GetFileType(std::string theInput,char *theOutput);
		void AddDirToDir(Validator::MetaDirectory &theDir,std::vector<std::string> theDirNameColl);
		bool AddFile(Validator::MetaDirectory &theDir,std::string theDirName,Validator::MetaFile theFile);
		std::string filename_without_type(std::string filename);
};


#endif

